home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / atlvcl.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  40.0 KB  |  1,312 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // ATLVCL.H - Provides the connective tissue between
  3. //            the ATL framework and VCL components.
  4. //
  5. // $Revision:   1.44.3.3  $
  6. // $Date:   05 Feb 1998 20:22:40  $
  7. //
  8. // Copyright (c) 1998 Borland International
  9. /////////////////////////////////////////////////////////////////////////////
  10.  
  11. #ifndef __ATLVCL_H_
  12. #define __ATLVCL_H_
  13.  
  14. #pragma option push -VF
  15.  
  16. // These are required due to RTL differences between VC++ and BCB
  17. //
  18. #define _ATL_NO_FORCE_LIBS
  19. #define _ATL_NO_DEBUG_CRT
  20.  
  21. // Defines _ASSERTE et al.
  22. //
  23. #include <utilcls.h>
  24.  
  25. // Delta for remapping messages for VCL compatibility
  26. //
  27. #if !defined(OCM_BASE)
  28.   #define OCM_BASE (int)(8192)
  29. #endif
  30.  
  31. #if !defined(__ATLBASE_H)
  32.   #include <atl\atlbase.h>
  33. #endif
  34.  
  35. #include <sysdefs.h>
  36. #include <objbase.h>
  37. #include <dstring.h>
  38. #include <wstring.h>
  39. #include <sysutils.hpp>
  40. #include <cguid.h>
  41. #include <dir.h>
  42.  
  43. // Externs
  44. //
  45. extern void* SaveInitProc;
  46.  
  47. // Prototype of routines implemented in ATLVCL.CPP
  48. //
  49. bool __fastcall AutomationTerminateProc();
  50. void __fastcall SaveVCLComponentToStream(TComponent *instance, LPSTREAM pStream);
  51. void __fastcall LoadVCLComponentFromStream(TComponent *instance, LPSTREAM pStream);
  52. TWinControl*    CreateReflectorWindow(HWND parent, Controls::TControl* Control);
  53.  
  54. // Forward Ref. (Avoids explicit inclusion of AXCTRLS.HPP)
  55. //
  56. namespace Axctrls
  57. {
  58.   extern PACKAGE HWND __fastcall ParkingWindow(void);
  59. }
  60.  
  61. // Forward Ref. (Avoids explicit inclusion of BDEPROV.HPP)
  62. //
  63. namespace Bdeprov
  64. {
  65.   extern PACKAGE void __fastcall UseBdeProv(void);
  66. };
  67.  
  68.  
  69. // Default MiscStatus Flags of Object
  70. //
  71. const DWORD dwDefaultControlMiscFlags = OLEMISC_RECOMPOSEONRESIZE | OLEMISC_CANTLINKINSIDE |
  72.                                         OLEMISC_INSIDEOUT | OLEMISC_ACTIVATEWHENVISIBLE |
  73.                                         OLEMISC_SETCLIENTSITEFIRST;
  74.                            
  75. // Declares routine that returns OLEMISC_xxxx Values
  76. //                           
  77. #define DECLARE_OLEMISC_FLAGS(flags)  \
  78. static DWORD _GetObjectMiscStatus()   \
  79. {                         \
  80.   return flags;           \
  81. }
  82.  
  83. // Declares tables of Verbs (Actions) support by object
  84. //                           
  85. #define BEGIN_VERB_MAP()            \
  86. static const OLEVERB* _GetVerbs()   \
  87. {                                   \
  88.   static const OLEVERB  _verbs[]=   \
  89.   {
  90.  
  91. #define VERB_ENTRY_EX(verbId, verbString, mfFlags, verbAttrib)  \
  92.       {verbId, verbString, mfFlags, verbAttrib },
  93.       
  94. #define VERB_ENTRY(verbId, verbString)  \
  95.          VERB_ENTRY_EX(verbId, verbString, 0 /* No MF_xxxx Flags */, OLEVERBATTRIB_ONCONTAINERMENU)
  96.   
  97. #define END_VERB_MAP()  \
  98.       { 0, 0, 0, 0 }    \
  99.   };                    \
  100.   return _verbs;        \
  101. };
  102.  
  103.  
  104. // TVclPtr wraps a pointer in order to perform lifetime mangement.
  105. //
  106. //
  107. // Template auto_ptr holds onto a pointer obtained via new and deletes that
  108. // object when it itself is destroyed (such as when leaving block scope).
  109. //
  110. // It can be used to make calls to new() exception safe.
  111. //
  112. template<class T> 
  113. class TVclPtr
  114. {
  115. public:
  116.    TVclPtr(T* p = 0) : m_ptr(p)                     {}
  117.    TVclPtr(TVclPtr<T>& src) : m_ptr(src.release())  {}
  118.    TVclPtr& operator= (TVclPtr<T>& rhs)             { reset(rhs.release()); return *this; }
  119.   ~TVclPtr()                                        { delete m_ptr; }
  120.  
  121.  
  122.       operator T* () const    { return m_ptr;}
  123.    T& operator *  () const    { _ASSERTE(m_ptr); return *m_ptr; }
  124.    T* operator->  () const    { _ASSERTE(m_ptr); return m_ptr;  }
  125.    T**  operator &()/*const*/ { return &m_ptr; }      
  126.    bool operator !() const    { return m_ptr == 0; }
  127.  
  128.    bool operator == (T* rhs)            const     { return m_ptr == rhs;}
  129.    bool operator == (const TVclPtr<T>& rhs) const { return m_ptr == rhs.m_ptr; }
  130.    bool operator != (T* rhs)            const     { return m_ptr != rhs;}
  131.    bool operator != (const TVclPtr<T>& rhs) const { return m_ptr != rhs.m_ptr; }
  132.  
  133.  
  134.    T* get        () const   { return m_ptr;    }
  135.    T* release    ()         { return reset(0); }
  136.    T* reset      (T* p = 0) { T* tmp = m_ptr; m_ptr = p; return tmp; }
  137.  
  138. private:
  139.     T* m_ptr;
  140. };
  141.  
  142.  
  143. // TComModule enhances ATL's CComModule
  144. // It is designed to support both in-process and out-of-process servers and handle
  145. // some VCL requirements.
  146. //
  147. class TComModule: public CComModule
  148. {
  149. public:
  150.   TComModule(): m_ThreadID(0), m_bRun(true), m_bExe(false), m_InitProc(0), m_bAutomationServer(false)
  151.   {}
  152.  
  153.   TComModule(TProcedure InitProcedure): m_ThreadID(0), m_bRun(true), 
  154.                                         m_bExe(true), m_InitProc(InitProcedure),
  155.                                         m_bAutomationServer(false)
  156.   {
  157.     // Ensure OLE was properly initialized
  158.     //
  159.     _ASSERTE(!!m_InitOle);
  160.  
  161.     if (m_bExe && m_InitProc)
  162.     {
  163.       SaveInitProc = System::InitProc;
  164.       System::InitProc = m_InitProc;
  165.     }
  166.   }
  167.  
  168.  ~TComModule(void)
  169.   {
  170.     if (m_bRun && m_bExe)
  171.     {
  172.       RevokeClassObjects();
  173.     }
  174.   }
  175.  
  176.   void DoFileAndObjectRegistration()
  177.   {
  178.     TSysCharSet DelimSet;
  179.     DelimSet << '/' << '-';
  180.     if (FindCmdLineSwitch("REGSERVER", DelimSet, true))
  181.     {
  182.       RegisterServer(TRUE);
  183.       m_bRun = false;
  184.     }
  185.     else if (FindCmdLineSwitch("UNREGSERVER", DelimSet, true))
  186.     {
  187.       UnregisterServer();
  188.       m_bRun = false;
  189.     }
  190.     else if (!(FindCmdLineSwitch("AUTOMATION", DelimSet, true) ||
  191.            FindCmdLineSwitch("EMBEDDING", DelimSet, true)))
  192.       RegisterServer(TRUE);
  193.     if (m_bRun)
  194. #ifdef _ATL_SINGLEUSE_INSTANCING
  195.       RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE);
  196. #else
  197.       RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE);
  198. #endif
  199.     else
  200.       exit(EXIT_SUCCESS);
  201.   }
  202.  
  203.   // Data members
  204.   //
  205.   DWORD       m_ThreadID;             // Thread identifier of module
  206.   bool        m_bRun;                 // Flags whether to run server
  207.   bool        m_bExe;                 // Flags Local server
  208.   bool        m_bAutomationServer;    // Flags module's for Automation Server
  209.   TProcedure  m_InitProc;             // Hold VCL's InitProc
  210.   TInitOle    m_InitOle;              // Object to initialize OLE
  211.  
  212.   LONG        Unlock();
  213.  
  214. };
  215.  
  216. // _Module is assumed to be a reference to a TComModule 
  217. // User may define _Module to be a ref. to an instance of a class derived 
  218. // from TComModule.
  219. //
  220. extern TComModule &_Module;
  221.  
  222. #if !defined(__ATLCOM_H__) 
  223.   #include <atl\atlcom.h>
  224. #endif
  225. #include   <shellapi.h>
  226. #if !defined(__ATLCTL_H__)
  227.   #include <atl\atlctl.h>
  228. #endif
  229.  
  230. #include <vcl.h> 
  231. #include <databkr.hpp>
  232. #include <atl\axform.h>
  233.  
  234. // Forward type Declaration
  235. //
  236. template <class T> class DELPHICLASS TWinControlAccess;
  237.  
  238. // Forward function declarations
  239. //
  240. void __fastcall InitAtlServer(void);
  241.  
  242. /* IDataBroker support */
  243.  
  244. // IDataBrokerImpl class implements IDataBroker interface, and is
  245. // used to publish datasets residing in a TDataModule.
  246. //
  247. template <class DM, class T, class Intf, const IID* piid, const GUID* plibid>
  248. class ATL_NO_VTABLE IDataBrokerImpl: public IDispatchImpl<Intf, piid, plibid>
  249. {
  250. public:
  251.   DM* m_DataModule;
  252.  
  253.   IDataBrokerImpl()
  254.   {
  255.     m_DataModule = new DM(NULL);
  256.   }
  257.  ~IDataBrokerImpl()
  258.   {
  259.     // Forces a reference to bdeprov.obj so that initialization code
  260.     // is executed.
  261.     //
  262.     Bdeprov::UseBdeProv();
  263.     m_DataModule->Free();
  264.   }
  265.  
  266.   HRESULT IDataBroker_GetProviderNames(System::OleVariant &Result)
  267.   {
  268.     unsigned int TICount;
  269.     _di_ITypeInfo TI;
  270.     TVclPtr<Classes::TStringList> ProvProps(new TStringList);
  271.  
  272.     HRESULT hres = GetTypeInfoCount(&TICount);
  273.     if (hres != S_OK) 
  274.       return hres;
  275.  
  276.     if (TICount)
  277.     {
  278.       hres = GetTypeInfo(0, 0, &TI);
  279.       if (hres != S_OK) 
  280.         return hres;
  281.       Databkr::EnumIProviderProps(TI, ProvProps);
  282.       ::VariantClear(&(VARIANT&)Result);
  283.       Result = Databkr::VarArrayFromStrings(ProvProps);
  284.     }
  285.     return S_OK;
  286.   }
  287.  
  288.   // IDataBroker
  289.   //
  290.   HRESULT STDMETHODCALLTYPE GetProviderNames(System::OleVariant &Result)
  291.   {
  292.     ATLTRACE(_T("IDataBroker::GetProviderNames\n"));
  293.     HRESULT hres;
  294.     try
  295.     {
  296.       hres = static_cast<T*>(this)->IDataBroker_GetProviderNames(Result);
  297.     }
  298.     catch (Exception& e)
  299.     {
  300.       return (static_cast<T*>(this))->Error(e.Message.c_str());
  301.     }
  302.     return hres;
  303.   }
  304. };
  305.  
  306.  
  307. // ISimpleFrameSite support 
  308. //
  309. template <class T>
  310. class ATL_NO_VTABLE ISimpleFrameSiteImpl
  311. {
  312. public:
  313.   // IUnknown
  314.   STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
  315.   _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistImpl)
  316.  
  317.   // ISimpleFrameSite
  318.   STDMETHOD(PreMessageFilter)(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp,
  319.                               LRESULT* plResult, DWORD* pdwCookie)
  320.   {
  321.     ATLTRACE(_T("ISimpleFrameImpl::PreMessageFilter\n"));
  322.     T* pT = static_cast<T*>(this);
  323.     return pT->ISimpleFrameSite_PreMessageFilter(hWnd, msg, wp, lp, plResult, pdwCookie);
  324.   }
  325.  
  326.   STDMETHOD(PostMessageFilter)(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp,
  327.                                LRESULT* plResult, DWORD dwCookie)
  328.   {
  329.     ATLTRACE(_T("ISimpleFrameImpl::PostMessageFilter\n"));
  330.     T* pT = static_cast<T*>(this);
  331.     return pT->ISimpleFrameSite_PostMessageFilter(hWnd, msg, wp, lp, plResult, dwCookie);
  332.   }
  333. };
  334.  
  335. /* ActiveX control support */
  336.  
  337. // TVclComControl is an ATL ActiveX control which encapsulates a VCL control
  338. // T  is the user's class which implements the OLE Control.
  339. // TVCL is the VCL type which is exposed as an ActiveX Control.
  340. //
  341. template <class T, class TVCL>
  342. class ATL_NO_VTABLE TVclComControl: public CComControlBase, public CMessageMap
  343. {
  344. public:
  345.   TVclComControl(void): m_VclCtl(0), m_VclWinCtl(0), m_hWnd(0),
  346.                         m_CtlWndProc(0), CComControlBase(m_hWnd)
  347.   {
  348.     m_bWindowOnly = TRUE;
  349.   }
  350.  
  351.  ~TVclComControl(void)
  352.   {
  353.     if (m_VclCtl)
  354.     {
  355.       m_VclCtl->WindowProc = m_CtlWndProc;
  356.       delete m_VclCtl;
  357.     }
  358.     if ((m_VclWinCtl) && ((TWinControl*)m_VclWinCtl != (TWinControl*)m_VclCtl))
  359.       delete m_VclWinCtl;
  360.   }
  361.  
  362.   // IOleObject support
  363.   //
  364.   HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite)
  365.   {
  366.     HRESULT hres = CComControlBase::IOleObject_SetClientSite(pClientSite);
  367.     if (hres == S_OK)
  368.     {
  369.       if (m_spClientSite != NULL)
  370.       {
  371.         DWORD MiscFlags;
  372.         hres = static_cast<T*>(this)->GetMiscStatus(DVASPECT_CONTENT, &MiscFlags);
  373.  
  374.         if (!SUCCEEDED(hres))
  375.           return hres;
  376.  
  377.         // The following double checks that the registry entry indeed corresponds to
  378.         // the value specified by our Control. (NOTE: IOleObject's implementation
  379.         // looks up the value in the registry).
  380.         //
  381.         _ASSERTE(MiscFlags == static_cast<T*>(this)->_GetObjectMiscStatus());
  382.                   
  383.         if (MiscFlags & OLEMISC_SIMPLEFRAME)
  384.         {
  385.           m_spClientSite->QueryInterface(IID_ISimpleFrameSite,
  386.                                         (void**)&m_spSimpleFrameSite);
  387.         }
  388.  
  389.         // Initialize the helper class used to get ambient properties from the container
  390.         m_AmbientDriver.Bind(m_spClientSite);
  391.  
  392.         // Get ambient properties from the container and update the control
  393.         static_cast<T*>(this)->OnAmbientPropertyChange(0);
  394.  
  395.         // Enable Ctl3D style
  396.         m_VclWinCtl->Perform(CM_PARENTCTL3DCHANGED, 1, 1);
  397.       }
  398.       else
  399.       {
  400.         m_spSimpleFrameSite = NULL;
  401.         m_AmbientDriver = NULL;
  402.       }
  403.     }
  404.     else
  405.     {
  406.       m_spClientSite = NULL;
  407.       m_AmbientDriver = NULL;
  408.     }
  409.     return hres;
  410.   }
  411.  
  412.   // IPersistStreamInit support
  413.   //
  414.   HRESULT IPersistStreamInit_Save(LPSTREAM pStm, BOOL /* fClearDirty */, ATL_PROPMAP_ENTRY* pMap)
  415.   {
  416.     try
  417.     {
  418.       ::SaveVCLComponentToStream(m_VclCtl, pStm);
  419.       //!?? Clear fClearDirty flag
  420.     }
  421.     catch (Exception& e)
  422.     {
  423.       return (static_cast<T*>(this))->Error(e.Message.c_str());
  424.     }
  425.     return S_OK;
  426.   }
  427.  
  428.   HRESULT IPersistStreamInit_Load(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap)
  429.   {
  430.     try
  431.     {
  432.       ::LoadVCLComponentFromStream(m_VclCtl, pStm);
  433.     }
  434.     catch (Exception& e)
  435.     {
  436.       return (static_cast<T*>(this))->Error(e.Message.c_str());
  437.     }
  438.     return S_OK;
  439.   }
  440.  
  441.   // ISimpleFrameSite support
  442.   //
  443.   HRESULT ISimpleFrameSite_PreMessageFilter(HWND hWnd, UINT msg, WPARAM wp,
  444.                                             LPARAM lp, LRESULT* plResult, DWORD* pdwCookie)
  445.   {
  446.     if (m_spSimpleFrameSite)
  447.       return m_spSimpleFrameSite->PreMessageFilter(hWnd, msg, wp, lp,
  448.                                                    plResult, pdwCookie);
  449.     else
  450.       return S_OK;
  451.   }
  452.  
  453.   HRESULT ISimpleFrameSite_PostMessageFilter(HWND hWnd, UINT msg, WPARAM wp,
  454.                                              LPARAM lp, LRESULT* plResult, DWORD dwCookie)
  455.   {
  456.     if (m_spSimpleFrameSite)
  457.       return m_spSimpleFrameSite->PostMessageFilter(hWnd, msg, wp, lp,
  458.                                                     plResult, dwCookie);
  459.     else
  460.       return S_OK;
  461.   }
  462.  
  463.  
  464.   // IPropertyNotifySink Support methods
  465.   //
  466.   // NOTE: If your control class derives from IPropertyNotifySink, this method calls 
  467.   // CFirePropNotifyEvent::FireOnRequestEdit to notify all connected IPropertyNotifySink interfaces 
  468.   // that the specified control property is about to change. If your control class does not derive 
  469.   // from IPropertyNotifySink, this method returns S_OK.
  470.   //
  471.   HRESULT FireOnRequestEdit(DISPID dispID)
  472.   {
  473.     T* pT = static_cast<T*>(this);
  474.     return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID);
  475.   }
  476.  
  477.   // If your control class derives from IPropertyNotifySink, this method calls 
  478.   // CFirePropNotifyEvent::FireOnChanged to notify all connected IPropertyNotifySink interfaces 
  479.   // that the specified control property has changed. If your control class does not derive from 
  480.   // IPropertyNotifySink, this method returns S_OK
  481.   //
  482.   HRESULT FireOnChanged(DISPID dispID)
  483.   {
  484.     T* pT = static_cast<T*>(this);
  485.     return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID);
  486.   }
  487.  
  488.   // Retrieves pointer to requested interface
  489.   // NOTE: Limited to interfaces listed in COM map table
  490.   //
  491.   virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
  492.   {
  493.     T* pT = static_cast<T*>(this);
  494.     return pT->_InternalQueryInterface(iid, ppv);
  495.   }
  496.  
  497.   // Creates underlying window of the control.
  498.   // NOTE: You may override this method to do something other than create an window (for
  499.   //   example, to create two windows, one of which becomes a toolbar for your control).
  500.   //  
  501.   HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
  502.   {
  503.     T* pT = static_cast<T*>(this);
  504.     return pT->Create(hWndParent, rcPos);
  505.   }
  506.  
  507.   // Returns the handle of the control, if successful. Otherwise, returns NULL.
  508.   //
  509.   HWND Create(HWND hWndParent, RECT& rcPos);
  510.  
  511.   // Sets the Window's show state (See ::ShowWindow of WIN32 SDK for details on 'nCmdShow')
  512.   //
  513.   BOOL ShowWindow(int nCmdShow)
  514.   {
  515.     _ASSERTE(m_hWnd);
  516.     return ::ShowWindow(m_hWnd, nCmdShow);
  517.   }
  518.  
  519.   // Overridable Message Handler method of Control.
  520.   // NOTE: You may intercept messages in your control via an ATL Message Map.
  521.   //   The default implementation of this method is to dispatch messages
  522.   //   via the Message Map. If the message was not handled via a message
  523.   //   map, the message is dispatched to the underlying VCL handler.
  524.   //
  525.   virtual void ControlWndProc(Messages::TMessage& Message);
  526.  
  527.   // Procedure handling messages of this control
  528.   //
  529.   virtual void __fastcall WndProc(Messages::TMessage& Message);
  530.  
  531.   // Method which destroys and re-create the control's window. 
  532.   // NOTE: This may be necessary if you need to change the window's style bits.
  533.   //
  534.   void RecreateWnd();
  535.  
  536.   // Data members
  537.   //
  538.   HWND m_hWnd;                    // Underlying Window Handle of our Control 
  539.  
  540. protected:
  541.   virtual void InitializeControl() 
  542.   {}
  543.  
  544.   void         Initialize();
  545.  
  546.  
  547.   TWinControlAccess<TWinControl>*   m_VclWinCtl;
  548.   TWinControlAccess<TVCL>*          m_VclCtl;
  549.   TAutoDriver<IDispatch>            m_AmbientDriver;
  550.  
  551. private:
  552.   TWndMethod                        m_CtlWndProc;
  553.   CComPtr<ISimpleFrameSite>         m_spSimpleFrameSite;
  554. };
  555.  
  556.  
  557.  
  558. // TVclComControl::Initialize
  559. //
  560. template <class T, class TVCL> void 
  561. TVclComControl<T, TVCL>::Initialize(void)
  562. {
  563.   // Retrieve handle to reflector Window defined in AXCTRLS unit
  564.   //
  565.   HWND hwndParkingWindow = Axctrls::ParkingWindow();
  566.  
  567.   // Create VCL Object Wrapper for our Control
  568.   //
  569.   // jmt m_VclCtl = new TWinControlAccess<TVCL>(hwndParkingWindow);
  570.   m_VclCtl = (TWinControlAccess<TVCL>*)(TVCL::CreateParentedControl(__classid(TWinControlAccess<TVCL>), (int)hwndParkingWindow));
  571.  
  572.   // Test whether our control requires message reflection and create a reflector window if yes
  573.   //
  574.   if (m_VclCtl->ControlStyle.Contains(csReflector))
  575.     (TWinControl*)m_VclWinCtl = ::CreateReflectorWindow(hwndParkingWindow, m_VclCtl);
  576.   else
  577.     (TWinControl*)m_VclWinCtl = (TWinControl*)m_VclCtl;
  578.  
  579.   // Update the Window Procedure variables
  580.   //
  581.   m_CtlWndProc = m_VclCtl->WindowProc;
  582.   m_VclCtl->WindowProc = WndProc;
  583.  
  584.   // Invoke virtual allowing Control to perform additional initialization
  585.   //
  586.   InitializeControl();
  587.   ATLTRACE(_T("VCL control created and initialized\n"));
  588. }
  589.  
  590.  
  591. // TVclComControl::ReCreateWnd
  592. //
  593. template <class T, class TVCL> void 
  594. TVclComControl<T, TVCL>::RecreateWnd()
  595. {
  596.   if (m_VclWinCtl->HandleAllocated())
  597.   {
  598.     RECT CtlBounds = m_VclWinCtl->BoundsRect;
  599.     HWND PrevWnd = ::GetWindow(m_VclWinCtl->Handle, GW_HWNDPREV);
  600.  
  601.     // set ATL window handle to NULL to prevent InPlaceDeactiveate()
  602.     // from destroying the VCL control window too soon
  603.     //
  604.     m_hWndCD = NULL;
  605.     IOleInPlaceObject_InPlaceDeactivate();
  606.     m_VclWinCtl->DoDestroyHandle();
  607.     m_VclWinCtl->UpdateControlState();
  608.     if (InPlaceActivate(m_bUIActive ? OLEIVERB_INPLACEACTIVATE : OLEIVERB_HIDE,
  609.                         &CtlBounds) == S_OK)
  610.       ::SetWindowPos(m_VclWinCtl->Handle, PrevWnd, 0, 0, 0, 0,
  611.                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  612.   }
  613. }
  614.  
  615.  
  616. // TVclComControl::Create
  617. //
  618. template <class T, class TVCL> HWND 
  619. TVclComControl<T, TVCL>::Create(HWND hWndParent, RECT& rcPos)
  620. {
  621.   _ASSERTE(m_VclCtl);
  622.  
  623.   // Set the parent handle here because with a parking window of NULL.  The
  624.   // window is not created until the parent is set.
  625.   //
  626.   m_VclWinCtl->ParentWindow = hWndParent;
  627.   m_VclWinCtl->BoundsRect = rcPos;
  628.  
  629.   // For ActiveForms the window handle will be NULL at this point; so, force create.
  630.   //
  631.   m_VclWinCtl->HandleNeeded();
  632.  
  633.   // For ActiveForms again, the window will not be visible. So, show it.
  634.   //
  635.   m_VclWinCtl->Visible = true;
  636.  
  637.   // Update and return handle
  638.   //
  639.   m_hWnd = m_VclWinCtl->GetWindowHandle();
  640.   return m_hWnd;
  641. }
  642.  
  643.  
  644. // TVclComControl::ControlWndProc
  645. //
  646. template <class T, class TVCL> void 
  647. TVclComControl<T, TVCL>::ControlWndProc(Messages::TMessage& Message)
  648. {
  649.   if ((Message.Msg >= OCM_BASE) && (Message.Msg < OCM_BASE + WM_USER))
  650.     Message.Msg = Message.Msg + (CN_BASE - OCM_BASE);
  651.  
  652.   // Allow ATL message maps to intercept messages before they are dispatch to VCL handlers
  653.   //    
  654.   if (!ProcessWindowMessage(m_VclCtl->GetWindowHandle(), Message.Msg,
  655.                             Message.WParam, Message.LParam,
  656.                             *((LRESULT*)(&Message.Result)), 0))
  657.     m_CtlWndProc(Message);
  658.  
  659.   if ((Message.Msg >= CN_BASE) && (Message.Msg < CN_BASE + WM_USER))
  660.     Message.Msg = Message.Msg - (CN_BASE - OCM_BASE);
  661. }
  662.  
  663.  
  664. // TvclComControl::WndProc
  665. // Procedure handling messages of this control
  666. //
  667. template <class T, class TVCL> void __fastcall 
  668. TVclComControl<T, TVCL>::WndProc(Messages::TMessage& Message)
  669. {
  670.   DWORD dwCookie;
  671.   HWND Handle = m_VclCtl->GetWindowHandle();
  672.   bool FilterMessage = ((Message.Msg < CM_BASE) || (Message.Msg >= 0xC000)) && 
  673.                        m_spSimpleFrameSite && m_bInPlaceActive;
  674.   if (FilterMessage)
  675.   {
  676.     if (m_spSimpleFrameSite->PreMessageFilter(Handle,
  677.                                               Message.Msg, Message.WParam, 
  678.                                               Message.LParam, (LRESULT*)&Message.Result,
  679.                                               &dwCookie) == S_FALSE)
  680.       return;
  681.   }
  682.  
  683.   T* pT = static_cast<T*>(this);
  684.   CComPtr<IOleControlSite> spSite;
  685.   switch (Message.Msg)
  686.   {
  687.   case WM_SETFOCUS:
  688.   case WM_KILLFOCUS:
  689.     ControlWndProc(Message);
  690.     m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&spSite);
  691.     if (spSite)
  692.       spSite->OnFocus(Message.Msg == WM_SETFOCUS);
  693.     break;
  694.  
  695.   case CM_VISIBLECHANGED:
  696.     if ((TWinControl*)m_VclCtl != (TWinControl*)m_VclWinCtl)
  697.       m_VclWinCtl->Visible = m_VclCtl->Visible;
  698.     if (!(m_VclWinCtl->Visible))
  699.       IOleInPlaceObject_UIDeactivate();
  700.     ControlWndProc(Message);
  701.     break;
  702.  
  703.   case CM_RECREATEWND:
  704.     if ((m_bInPlaceActive) && ((TWinControl*)m_VclCtl == (TWinControl*)m_VclWinCtl))
  705.       RecreateWnd();
  706.     else
  707.     {
  708.       ControlWndProc(Message);
  709.       pT->SendOnViewChange(DVASPECT_CONTENT);
  710.     }
  711.     break;
  712.  
  713.   case CM_INVALIDATE:
  714.   case WM_SETTEXT:
  715.     ControlWndProc(Message);
  716.     if (!m_bInPlaceActive)
  717.       pT->SendOnViewChange(DVASPECT_CONTENT);
  718.     break;
  719.  
  720.   case WM_NCHITTEST:
  721.     ControlWndProc(Message);
  722.     if (Message.Result == HTTRANSPARENT)
  723.       Message.Result = HTCLIENT;
  724.     break;
  725.  
  726.   default:
  727.     ControlWndProc(Message);
  728.   }
  729.   if (FilterMessage)
  730.     m_spSimpleFrameSite->PostMessageFilter(Handle, Message.Msg,
  731.                          Message.WParam, 
  732.                          Message.LParam, 
  733.                          (LRESULT*)&Message.Result, 
  734.                          dwCookie);
  735. }
  736.  
  737.  
  738. // TWinControlAccess: Template which wraps the Window interface of an ActiveX Control
  739. //
  740. template <class T>
  741. class TWinControlAccess: public T
  742. {
  743.   __fastcall virtual TWinControlAccess(Classes::TComponent* AOwner): T(AOwner) {}
  744. public:
  745.   __fastcall TWinControlAccess(HWND ParentWindow): T(ParentWindow) {}
  746.   HWND GetWindowHandle(void) {return WindowHandle;}
  747.   void DoDestroyHandle(void) {DestroyHandle();}
  748. };
  749.  
  750.  
  751. // TVclControlImpl
  752. //
  753. template <class T,                        // User class implementing Control
  754.           class TVCL,                     // Underlying VCL type used in One-Step Conversion
  755.           const CLSID* pclsid,            // Class ID of Control
  756.           const IID* piid,                // Primary interface of Control
  757.           const IID* peventsid,           // Event (outgoing) interface of Control
  758.           const GUID* plibid>             // GUID of TypeLibrary
  759. class ATL_NO_VTABLE TVclControlImpl:
  760.       public CComObjectRootEx<CComObjectThreadModel>, 
  761.       public CComCoClass<T, pclsid>,
  762.       public TVclComControl<T, TVCL>,
  763.       public IProvideClassInfo2Impl<pclsid, peventsid, plibid>,
  764.       public IPersistStreamInitImpl<T>,
  765.       public IPersistStorageImpl<T>,
  766.       public IQuickActivateImpl<T>,
  767.       public IOleControlImpl<T>,
  768.       public IOleObjectImpl<T>,
  769.       public IOleInPlaceActiveObjectImpl<T>,
  770.       public IViewObjectExImpl<T>,
  771.       public IOleInPlaceObjectWindowlessImpl<T>,
  772.       public IDataObjectImpl<T>,
  773.       public ISpecifyPropertyPagesImpl<T>,
  774.       public IConnectionPointContainerImpl<T>,
  775.       public IPropertyNotifySinkCP<T, CComDynamicUnkArray>,
  776.       public ISupportErrorInfo,
  777.       public ISimpleFrameSiteImpl<T>
  778. {
  779. public:
  780.  
  781.   TVclControlImpl() 
  782.   {}
  783.  
  784.  ~TVclControlImpl() 
  785.   {}
  786.  
  787.   // Returns pointer to outer IUnknown 
  788.   // 
  789.   virtual IUnknown* GetControllingUnknown()
  790.   {
  791.     return (static_cast<T*>(this))->GetUnknown();
  792.   }
  793.  
  794.   // Empty Message Map provides default implementation of 'ProcessWindowMessage'
  795.   // 
  796.   BEGIN_MSG_MAP(TVclControlImpl)
  797.   END_MSG_MAP()
  798.  
  799.   // Map of connection points supported 
  800.   // 
  801.   BEGIN_CONNECTION_POINT_MAP(T)
  802.      CONNECTION_POINT_ENTRY(*peventsid)
  803.      CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
  804.   END_CONNECTION_POINT_MAP()
  805.  
  806.   // This macro declares a static routine which returns the default OLEMISC_xxxx
  807.   // flags used for controls. The macro may be redefined in the derived class
  808.   //  to specify other OLEMISC_xxxx values.
  809.   //  
  810.   DECLARE_OLEMISC_FLAGS(dwDefaultControlMiscFlags);
  811.  
  812.   // Verbs supported by Control. Provides default implementation of _GetVerbs()
  813.   // This table can be redefined in the user's class if the latter supports additional 
  814.   // Verbs (or does not want the default 'Properties' verb).
  815.   //
  816.   BEGIN_VERB_MAP()
  817.     VERB_ENTRY(0, L"Properties")
  818.   END_VERB_MAP()
  819.  
  820.   // IOleInPlaceObject
  821.   //
  822.   STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
  823.   {
  824.     try
  825.     {
  826.       if (m_VclWinCtl)
  827.         m_VclWinCtl->SetBounds(prcPos->left, prcPos->top,
  828.                      prcPos->right - prcPos->left, prcPos->bottom - prcPos->top);
  829.     }
  830.     catch (Exception& e)
  831.     {
  832.       return (static_cast<T*>(this))->Error(e.Message.c_str());
  833.     }
  834.     return S_OK;
  835.   }
  836.  
  837.  
  838.   HRESULT FinalConstruct()
  839.   {
  840.     try
  841.     {
  842.       Initialize();
  843.     }
  844.     catch(Exception &e)
  845.     {
  846.       return (static_cast<T*>(this))->Error(e.Message.c_str());
  847.     }
  848.     return S_OK;
  849.     return S_OK;
  850.   }
  851.  
  852.   void FinalRelease()
  853.   {}
  854.  
  855.   // IViewObjectEx
  856.   //
  857.   STDMETHOD(GetViewStatus)(DWORD* pdwStatus)
  858.   {
  859.     ATLTRACE(_T("IViewObjectExImpl::GetViewStatus\n"));
  860.     *pdwStatus = VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE;
  861.     return S_OK;
  862.   }
  863.  
  864.   // ISupportErrorInfo
  865.   //
  866.   STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
  867.   {
  868.     ATLTRACE(_T("ISupportErrorInfo::InterfaceSupportsErrorInfo\n"));
  869.     T* pT = static_cast<T*>(this);
  870.     const _ATL_INTMAP_ENTRY *pentries = pT->_GetEntries();
  871.  
  872.     while (pentries->piid)
  873.     {
  874.       if (InlineIsEqualGUID(*(pentries->piid),riid))
  875.         return S_OK;
  876.       pentries++;
  877.     }
  878.     return S_FALSE;
  879.   }
  880.  
  881.   // IOleControl
  882.   // The following implementation supports BACKCOLOR, FORECOLOR, and FONT ambient
  883.   // properties.  Note that a VCL control will ignore the container's BACKCOLOR
  884.   // property unless the control's ParentColor property is True. FORECOLOR and
  885.   // FONT properties are ignored unless the control's ParentFont property is True.
  886.   //
  887.   STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
  888.   {
  889.     ATLTRACE(_T("IOleControl::OnAmbientPropertyChange\n"));
  890.     ATLTRACE(_T(" -- DISPID = %d (%d)\n"), dispid);
  891.     if (m_VclWinCtl == NULL || m_AmbientDriver == NULL)
  892.       return S_OK;
  893.     if (dispid == DISPID_AMBIENT_BACKCOLOR ||
  894.         dispid == 0)
  895.     {
  896.       TAutoArgs<0> arg;
  897.       HRESULT hres = m_AmbientDriver.OlePropertyGet(DISPID_AMBIENT_BACKCOLOR, arg);
  898.       if (hres != S_OK)
  899.         return hres;
  900.       m_VclWinCtl->Perform(CM_PARENTCOLORCHANGED, 1, arg.GetRetVariant());
  901.     }
  902.     if (dispid == DISPID_AMBIENT_FORECOLOR ||
  903.         dispid == DISPID_AMBIENT_FONT ||
  904.         dispid == 0)
  905.     {
  906.       TAutoArgs<0> arg;
  907.       TVclPtr<TFont> pFont = new TFont;
  908.       HRESULT hres = m_AmbientDriver.OlePropertyGet(DISPID_AMBIENT_FORECOLOR, arg);
  909.       if (hres != S_OK)
  910.         return hres;
  911.       pFont->Color = (int)arg.GetRetVariant();
  912.       hres = m_AmbientDriver.OlePropertyGet(DISPID_AMBIENT_FONT, arg);
  913.       if (hres != S_OK)
  914.         return hres;
  915.       SetOleFont(pFont, (IFontDisp*)(IUnknown*)arg.GetRetVariant());
  916.       m_VclWinCtl->Perform(CM_PARENTFONTCHANGED, 1, int(pFont.get()));
  917.     }
  918.     return S_OK;
  919.   }
  920.  
  921.   // IAtlSubCtl
  922.   //
  923.   HRESULT OnDraw(ATL_DRAWINFO& di)
  924.   {
  925.     try
  926.     {
  927.       if (m_VclCtl)
  928.         m_VclCtl->PaintTo(di.hdcDraw, di.prcBounds->left, di.prcBounds->top);
  929.     }
  930.     catch (Exception& e)
  931.     {
  932.       return (static_cast<T*>(this))->Error(e.Message.c_str());
  933.     }
  934.     return S_OK;
  935.   }
  936. };
  937.  
  938. // TValidateLicense - Standard implementation of 'IsLicenseValid' that simply returns
  939. //             TRUE. When Control Licensing support is enabled, the Wizard
  940. //             automatically assigns your control a GUID as the Runtime License
  941. //             string. However, your control still needs to validate whether the
  942. //             it is licensed on the machine (before handing out the runtime
  943. //             license string for example). This class provides a standard implementation
  944. //             of the validation routine that simply returns TRUE.
  945. //
  946. class TValidateLicense
  947. {
  948. public:
  949.   static BOOL IsGUIDInFile(const WCHAR *szGUID, const TCHAR *szLicFileName)
  950.   {
  951.     LPCTSTR pName = 0;
  952.  
  953.     // Find name of LicFileName
  954.     //
  955.     OFSTRUCT ofs;
  956.     ZeroMemory(&ofs, sizeof(ofs));
  957.     ofs.cBytes = sizeof(OFSTRUCT);
  958.  
  959.     // We'll look for the license file in the directory of the OCX..
  960.     // Then in the current, app, Windows, System or PATH directories!!
  961.     //
  962.     TCHAR szModule[_MAX_PATH];
  963.     ::GetModuleFileName(_Module.GetModuleInstance(), szModule, sizeof(szModule));
  964.     TCHAR szDir[_MAX_DIR];
  965.     TCHAR szDrv[_MAX_DRIVE];
  966.     _tfnsplit(szModule, szDrv, szDir, 0, 0);
  967.     _tfnmerge(szModule, szDrv, szDir, 0, 0);
  968.     lstrcat(szModule, szLicFileName);
  969.     if (::OpenFile(szModule, &ofs, OF_EXIST) != HFILE_ERROR ||
  970.         ::OpenFile(szLicFileName, &ofs, OF_EXIST) != HFILE_ERROR)
  971.     {
  972.       pName = ofs.szPathName;
  973.     }
  974.     else
  975.     {
  976.       // Could not find file anywhere
  977.       //
  978.       ATLTRACE(_T("Could not find License File\n"));
  979.       return false;
  980.     }
  981.  
  982.     // Create a TStringList and load from the file
  983.     //
  984.     _ASSERTE(pName);
  985.     TVclPtr<TStringList> pList = new TStringList;
  986.     pList->LoadFromFile(pName);
  987.     int index = pList->IndexOf(AnsiString(szGUID));
  988.     return (index != -1);
  989.   }
  990. };
  991.  
  992. // TLicenseString
  993. //  Template built around the runtime license string of a Control.
  994. // 'VerifyLicenseKey' compares string passed in to the runtime license key
  995. // 'GetLicenseKey'  returns the runtime license key
  996. // 'IsLicenseValid'   delegates to T::IsLicenseValid allowing a separate class to
  997. //               handle the license verification.
  998. //
  999. template <class T>
  1000. class TLicenseString
  1001. {
  1002. protected:
  1003.   static BOOL VerifyLicenseKey(BSTR str)
  1004.   {
  1005.     ATLTRACE(_T("TLicenseString::VerifyLicenseKey\n"));
  1006.     return !lstrcmpW(str, T::GetLicenseString());
  1007.   }
  1008.  
  1009.   static BOOL GetLicenseKey(DWORD /*dwReserved*/, BSTR *pStr)
  1010.   {
  1011.     ATLTRACE(_T("TLicenseString::GetLicenseKey\n"));
  1012.     *pStr = ::SysAllocString(T::GetLicenseString());
  1013.     return TRUE;
  1014.   }
  1015.  
  1016.   static BOOL IsLicenseValid()
  1017.   {
  1018.     ATLTRACE(_T("TLicenseString::IsLicenseValid\n"));
  1019.     return T::IsLicenseValid();
  1020.   }
  1021. };
  1022.  
  1023.  
  1024. #include <axctrls.hpp>
  1025. // TVCLPropertyPage
  1026. //
  1027. template <class T, const CLSID* pclsid, class ppclass>
  1028. class ATL_NO_VTABLE TVCLPropertyPage: public CComObjectRootEx<CComSingleThreadModel>,
  1029.                                       public IUnknown,
  1030.                                       public CComCoClass<T, pclsid>
  1031. {
  1032. public:
  1033.   TVCLPropertyPage(void): m_PPImpl(0), m_InnerUnk(0) 
  1034.   {}
  1035.  ~TVCLPropertyPage()
  1036.   {}
  1037.  
  1038.   DECLARE_PROTECT_FINAL_CONSTRUCT()
  1039.  
  1040.   HRESULT FinalConstruct(void)
  1041.   {
  1042.     ATLTRACE(_T("TVCLPropertyPage::FinalConstruct\n"));
  1043.     try
  1044.     {
  1045.       HRESULT hres = CComObjectRootEx<CComSingleThreadModel>::FinalConstruct();
  1046.       if (hres != S_OK) 
  1047.         return hres;
  1048.       IUnknown* pUnk = (static_cast<T*>(this))->GetUnknown();
  1049.       m_PPImpl = new TPropertyPageImpl(_di_IUnknown(pUnk));
  1050.       m_PPImpl->GetInterface(IID_IUnknown, &m_InnerUnk);
  1051.       m_PPImpl->PropertyPage = new ppclass((TComponent*)NULL);
  1052.       m_PPImpl->InitPropertyPage();
  1053.     }
  1054.     catch (Exception& e)
  1055.     {
  1056.       return (static_cast<T*>(this))->Error(e.Message.c_str());
  1057.     }
  1058.     return S_OK;
  1059.   }
  1060.  
  1061.   void FinalRelease(void)
  1062.   {
  1063.     ATLTRACE(_T("TVCLPropertyPage::FinalRelease\n"));
  1064.     try
  1065.     {
  1066.       if (m_PPImpl->PropertyPage) 
  1067.         delete m_PPImpl->PropertyPage;
  1068.       if (m_PPImpl) 
  1069.         delete m_PPImpl;
  1070.       CComObjectRootEx<CComSingleThreadModel>::FinalRelease();
  1071.     }
  1072.     catch (Exception& e)
  1073.     {
  1074.       // don't propagate exception
  1075.     }
  1076.   }
  1077.  
  1078.   // Data members
  1079.   //
  1080.   TPropertyPageImpl*              m_PPImpl;
  1081.   IUnknown*                       m_InnerUnk;
  1082. };
  1083.  
  1084.  
  1085. // TComServerRegistrar class performs registration for a COM server.
  1086. // An instance of this class is typically created via the
  1087. // DECLARE_COMSERVER_REGISTRY macro.
  1088. //
  1089. class TComServerRegistrar
  1090. {
  1091. public:
  1092.   TComServerRegistrar() : m_ClassID(CLSID_NULL)
  1093.   {
  1094.     Init();
  1095.   }
  1096.   TComServerRegistrar(const CLSID& clsid, AnsiString progID,
  1097.                       AnsiString description) : m_ClassID(clsid), m_ProgID(progID), 
  1098.                                                 m_Description(description)
  1099.   {
  1100.     Init();
  1101.   }
  1102.  ~TComServerRegistrar() 
  1103.   {}
  1104.  
  1105.   virtual HRESULT UpdateRegistry(bool Register);
  1106.   
  1107.   // Helpers to create/delete registry keys
  1108.   //
  1109.   static void  CreateRegKey(AnsiString Key, AnsiString ValueName, AnsiString Value);
  1110.   static void  DeleteRegKey(AnsiString Key);
  1111.   static void  NukeRegKey(AnsiString Key);
  1112.  
  1113. protected:
  1114.   AnsiString              m_ProgID;
  1115.   AnsiString              m_ClassKey;
  1116.   AnsiString              m_Description;
  1117.   AnsiString              m_ServerType;
  1118.   WideString              m_ModuleName;
  1119.   CLSID                   m_ClassID;
  1120.  
  1121.   // Helper routine to initialize some data members of class
  1122.   //
  1123.   void                    Init();
  1124. };
  1125.  
  1126. // TTypedComServerRegistrar class performs registration for a COM server
  1127. // which contains a type library (i.e., an automation server).
  1128. // An instance of this class is typically created via the
  1129. // DECLARE_TYPED_COMSERVER_REGISTRY macro.
  1130. //
  1131. class TTypedComServerRegistrar: public TComServerRegistrar
  1132. {
  1133. public:
  1134.   TTypedComServerRegistrar(): TComServerRegistrar() {}
  1135.  
  1136.   TTypedComServerRegistrar(const CLSID& clsid, AnsiString ProgID):
  1137.   TComServerRegistrar(clsid, ProgID, NULL) 
  1138.   {}
  1139.  
  1140.   // Overriden to perform additional Registration tasks
  1141.   //
  1142.   HRESULT UpdateRegistry(bool Register);
  1143. };
  1144.  
  1145.  
  1146. // TRemoteDataModuleRegistrar
  1147. //
  1148. class TRemoteDataModuleRegistrar : public TTypedComServerRegistrar
  1149. {
  1150. public:
  1151.   TRemoteDataModuleRegistrar() : TTypedComServerRegistrar() {}
  1152.  
  1153.   TRemoteDataModuleRegistrar(const CLSID& clsid, AnsiString ProgID):
  1154.   TTypedComServerRegistrar(clsid, ProgID) 
  1155.   {}
  1156.  
  1157.   // Overriden to perform additional Registration tasks
  1158.   //
  1159.   virtual HRESULT UpdateRegistry(bool Register);
  1160. };
  1161.  
  1162.   
  1163. // TAxControlRegistrar class performs registration for an ActiveX control.
  1164. // An instance of this class is typically created via the
  1165. // DECLARE_ACTIVEXCONTROL_FACTORY macro.
  1166. //
  1167. class TAxControlRegistrar: public TTypedComServerRegistrar
  1168. {
  1169. public:
  1170.   TAxControlRegistrar(): m_BitmapID(0), m_MiscFlags(dwDefaultControlMiscFlags), m_Verbs(0)
  1171.   {}
  1172.  
  1173.   TAxControlRegistrar(const CLSID& clsid,                           // CLSID of Object
  1174.                       AnsiString ProgID,                            // ProgId of Object
  1175.                       int BitmapID,                                 // Index of ToolboxBitmap32 res.
  1176.                       DWORD MiscFlags = dwDefaultControlMiscFlags,  // Object MISC_xxx flags
  1177.                       const OLEVERB *verbs = 0) :                   // Array of Verbs
  1178.                                                 m_BitmapID(BitmapID), 
  1179.                                                 m_MiscFlags(MiscFlags),
  1180.                                                 m_Verbs(verbs),
  1181.                                                 TTypedComServerRegistrar(clsid, ProgID)
  1182.   {}
  1183.  
  1184.   // Overriden to perform additional Registration tasks
  1185.   //
  1186.   virtual HRESULT UpdateRegistry(bool Register);
  1187.  
  1188. protected:
  1189.   int             m_BitmapID;     // Index of ToolboxBitmap32 Resource
  1190.   DWORD           m_MiscFlags;    // Inf. about Control's Designer's/behavior's aspect
  1191.   const OLEVERB*  m_Verbs;        // Array of OLEVERBs support be Control
  1192. };
  1193.  
  1194.  
  1195. // VCL_CONTROL_COM_INTERFACE_ENTRIES
  1196. //
  1197. //  This macro defines the entries of the required Interfaces for exposing a VCL
  1198. //  component as an ActiveX Control
  1199. //
  1200. #define  VCL_CONTROL_COM_INTERFACE_ENTRIES(intf)  \
  1201.   COM_INTERFACE_ENTRY_IMPL(IViewObjectEx) \
  1202.   COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx) \
  1203.   COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx) \
  1204.   COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless) \
  1205.   COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless) \
  1206.   COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject) \
  1207.   COM_INTERFACE_ENTRY_IMPL(IOleControl) \
  1208.   COM_INTERFACE_ENTRY_IMPL(IOleObject) \
  1209.   COM_INTERFACE_ENTRY_IMPL(IQuickActivate) \
  1210.   COM_INTERFACE_ENTRY_IMPL(IPersistStorage) \
  1211.   COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit) \
  1212.   COM_INTERFACE_ENTRY_IMPL(ISpecifyPropertyPages) \
  1213.   COM_INTERFACE_ENTRY_IMPL(IDataObject) \
  1214.   COM_INTERFACE_ENTRY_IMPL(ISimpleFrameSite) \
  1215.   COM_INTERFACE_ENTRY(IProvideClassInfo) \
  1216.   COM_INTERFACE_ENTRY(IProvideClassInfo2) \
  1217.   COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer) \
  1218.   COM_INTERFACE_ENTRY(ISupportErrorInfo) \
  1219.   COM_INTERFACE_ENTRY(intf) \
  1220.   COM_INTERFACE_ENTRY2(IDispatch, intf)
  1221.  
  1222.  
  1223. // VCLCONTROL_IMPL
  1224. // This macro is used to encapsulate the various base classes an ActiveX VCL Control derives from.
  1225. //
  1226. #define VCLCONTROL_IMPL(cppClass, CoClass, VclClass, intf, EventID) \
  1227.    public TVclControlImpl<cppClass, VclClass, &CLSID_##CoClass, &IID_##intf, &EventID, &LIBID_##CoClass>,\
  1228.    public IDispatchImpl<intf, &IID_##intf, &LIBID_##CoClass>, \
  1229.    public TEvents_##CoClass<cppClass>
  1230.  
  1231.  
  1232. #define  AUTOOBJECT_COM_INTERFACE_ENTRIES(intf) \
  1233.     COM_INTERFACE_ENTRY(intf)                   \
  1234.     COM_INTERFACE_ENTRY2(IDispatch, intf)
  1235.  
  1236. #define BEGIN_AUTOOBJECT_COM_MAP(coclass, intf) \
  1237.     BEGIN_COM_MAP(T##coclass)                   \
  1238.       AUTOOBJECT_COM_INTERFACE_ENTRIES(intf)
  1239.  
  1240. #define END_AUTOOBJECT_COM_MAP END_COM_MAP
  1241.  
  1242. #define  PROPERTYPAGE_COM_INTERFACE_ENTRIES                       \
  1243.      COM_INTERFACE_ENTRY(IUnknown)                                \
  1244.      COM_INTERFACE_ENTRY_AGGREGATE(IID_IPropertyPage, m_InnerUnk) \
  1245.      COM_INTERFACE_ENTRY_AGGREGATE(IID_IPropertyPage2, m_InnerUnk)
  1246.  
  1247. #define BEGIN_PROPERTYPAGE_COM_MAP(coclass) \
  1248.     BEGIN_COM_MAP(T##coclass) \
  1249.          PROPERTYPAGE_COM_INTERFACE_ENTRIES   
  1250.  
  1251. #define END_PROPERTYPAGE_COM_MAP END_COM_MAP
  1252.  
  1253. #define AUTOOBJECT_IMPL(cppClass, CoClass, intf)  \
  1254.   public CComObjectRootEx<CComObjectThreadModel>, \
  1255.   public CComCoClass<cppClass, &CLSID_##CoClass>, \
  1256.   public IDispatchImpl<intf, &IID_##intf, &LIBID_##CoClass>
  1257.  
  1258. #define REMOTEDATAMODULE_IMPL(cppClass, CoClass, VclClass, intf) \
  1259.   public CComObjectRootEx<CComObjectThreadModel>,                \
  1260.   public CComCoClass<cppClass, &CLSID_##CoClass>,                \
  1261.   public IDataBrokerImpl<VclClass, cppClass, intf, &IID_##intf, &LIBID_##CoClass>
  1262.  
  1263. #define DUALINTERFACE_IMPL(coclass, intf) \
  1264.    public IDispatchImpl<##intf, &IID_##intf, &LIBID_##coclass>
  1265.  
  1266. #define DUALINTERFACE_ENTRY(i) \
  1267.    COM_INTERFACE_ENTRY(i)
  1268.  
  1269. #define PROPERTYPAGE_IMPL(cppClass, CoClass, VclClass) \
  1270.    public TVCLPropertyPage<cppClass, &CLSID_##CoClass, VclClass>
  1271.  
  1272. #define UPDATE_REGISTRY_METHOD(code) \
  1273. static HRESULT WINAPI UpdateRegistry(BOOL bRegister)  \
  1274. { \
  1275.   HRESULT hres; \
  1276.   try \
  1277.   { \
  1278.    code \
  1279.   } \
  1280.   catch (Exception& e) \
  1281.   { \
  1282.    hres = Error(e.Message.c_str()); \
  1283.   } \
  1284.   return hres; \
  1285. }
  1286.  
  1287. #define DECLARE_COMSERVER_REGISTRY(progid, desc)                \
  1288.    UPDATE_REGISTRY_METHOD(                                      \
  1289.       TComServerRegistrar CSR(GetObjectCLSID(), progid, desc);  \
  1290.       hres = CSR.UpdateRegistry(bRegister);)
  1291.  
  1292. #define DECLARE_TYPED_COMSERVER_REGISTRY(progid)                \
  1293.    UPDATE_REGISTRY_METHOD(                                      \
  1294.     TTypedComServerRegistrar TCSR(GetObjectCLSID(), progid);    \
  1295.     hres = TCSR.UpdateRegistry(bRegister);)
  1296.  
  1297. #define DECLARE_REMOTEDATAMODULE_REGISTRY(progid)             \
  1298.    UPDATE_REGISTRY_METHOD(                                    \
  1299.   TRemoteDataModuleRegistrar TCSR(GetObjectCLSID(), progid);  \
  1300.   hres = TCSR.UpdateRegistry(bRegister);)
  1301.  
  1302. #define DECLARE_ACTIVEXCONTROL_REGISTRY(progid, idbmp) \
  1303. UPDATE_REGISTRY_METHOD( \
  1304.   TAxControlRegistrar AXCR(GetObjectCLSID(), progid, idbmp, _GetObjectMiscStatus(), _GetVerbs()); \
  1305.   hres = AXCR.UpdateRegistry(bRegister);)
  1306.  
  1307.  
  1308. #pragma option pop
  1309.  
  1310. #endif //__ATLVCL_H_
  1311.  
  1312.